package net.xinshi.advice;

import net.xinshi.commons.log.Log4j2MDCDatas;
import net.xinshi.exception.RestApiValidationRejectedException;
import net.xinshi.domain.ApiRequest;
import net.xinshi.utils.TidManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.TypeUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.lang.reflect.Type;

@ControllerAdvice
public class ApiRequestAdvice extends RequestBodyAdviceAdapter implements RequestBodyAdvice {

    private final Logger logger = LogManager.getLogger(getClass());
    private final boolean isLoggerDebugEnabled = logger.isDebugEnabled();

    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType,
                            Class<? extends HttpMessageConverter<?>> converterType) {
        return TypeUtils.isAssignable(ApiRequest.class, methodParameter.getParameterType());
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
                                Class<? extends HttpMessageConverter<?>> converterType) {
        ApiRequest pointsRequest = (ApiRequest) body;
        if (null == pointsRequest) {
            if (isLoggerDebugEnabled) {
                logger.debug("当前请求缺少REST接口请求对象");
            }
            throw new RestApiValidationRejectedException("缺少REST接口请求对象");
        }

        TidManager.setTid(pointsRequest.getTransactionUuid());

        String tid = pointsRequest.getTransactionUuid();

        String apiCode = null;
        String apiVersion = null;
        String apiName = null;
        String encodeMethod = null;
        String returnFormat = null;
        String remark = null;

        apiCode = pointsRequest.getApiId();
        encodeMethod = pointsRequest.getSignMethod();

        Log4j2MDCDatas.setTid(tid);
        Log4j2MDCDatas.setApiCode(apiCode);
        Log4j2MDCDatas.setEncodeMethod(encodeMethod);

        return pointsRequest;
    }

}
